package com.hikvision.open.app.ui.preview

import android.Manifest
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.Toast
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.fragment.app.FragmentActivity
import com.hikvision.hatomplayer.core.CorrectType
import com.hikvision.open.app.model.PlayStatus
import com.hikvision.open.app.utils.MyUtils
import com.hikvision.open.app.utils.PermissionHelper
import com.hikvision.open.app.utils.TrafficUtils
import com.hikvision.open.app.widget.PermissionDialog
import com.hikvision.open.app.widget.window.WindowGroupAdapter
import com.hikvision.open.app.widget.window.WindowItemView
import hik.sdk.demo.R
import hik.sdk.demo.databinding.ViewPreviewControlBinding
import java.text.MessageFormat

/**
 * <p> 预览控制View </p>
 * @author 段自航 2021/7/15 15:27
 * @version V1.0
 */
class PreviewControlView : ConstraintLayout, View.OnClickListener {

    private lateinit var viewBinding: ViewPreviewControlBinding
    private var previewUrl = "rtsp://admin:bjyx6688@192.168.1.121:554/"
    private var talkUrl = "rtsp://10.19.189.162:655/EUrl/nmCwkyk"

    /*总流量*/
    private var totalTraffic: Long = 0

    private var windowGroupHelper: WindowGroupAdapter? = null

    constructor(context: Context) : this(context, null)

    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        initView()
    }

    private fun initView() {
        setBackgroundResource(R.color.white)
        viewBinding = ViewPreviewControlBinding.inflate(LayoutInflater.from(context), this)
        viewBinding.previewUrlEdit.setText(previewUrl)
        viewBinding.talkUrlEdit.setText(talkUrl)
        //设置功能按钮点击监听
        viewBinding.openHardDecodeButton.setOnClickListener(this)
        viewBinding.closeHardDecodeButton.setOnClickListener(this)
        viewBinding.openSmartButton.setOnClickListener(this)
        viewBinding.closeSmartButton.setOnClickListener(this)
        viewBinding.startPreviewButton.setOnClickListener(this)
        viewBinding.stopPreviewButton.setOnClickListener(this)
        viewBinding.startTalkButton.setOnClickListener(this)
        viewBinding.stopTalkButton.setOnClickListener(this)
        viewBinding.openSoundButton.setOnClickListener(this)
        viewBinding.closeSoundButton.setOnClickListener(this)
        viewBinding.captureButton.setOnClickListener(this)
        viewBinding.startRecordButton.setOnClickListener(this)
        viewBinding.stopRecordButton.setOnClickListener(this)
        viewBinding.openFishEyeButton.setOnClickListener(this)
        viewBinding.exitFishEyeButton.setOnClickListener(this)
        viewBinding.fish180Button.setOnClickListener(this)
        viewBinding.fish360Button.setOnClickListener(this)
        viewBinding.fishOriginButton.setOnClickListener(this)
        viewBinding.fishPtzButton.setOnClickListener(this)
        viewBinding.fishCycButton.setOnClickListener(this)
        viewBinding.fishSemButton.setOnClickListener(this)
        viewBinding.fishCycSplButton.setOnClickListener(this)
        viewBinding.fishPlaButton.setOnClickListener(this)
        viewBinding.halfRateButton.setOnClickListener(this)
        viewBinding.getRateButton.setOnClickListener(this)
        viewBinding.decodeButton.setOnClickListener(this)
    }

    fun setWindowGroupHelper(windowGroupAdapter: WindowGroupAdapter) {
        this.windowGroupHelper = windowGroupAdapter
    }

    fun setPrivateFatio(fRatio: Float) {
        windowGroupHelper?.windowItemStructAllList?.let { windowList ->
            windowList.forEach { view ->
                val window = view as PlayWindowView
                if (window.getPlayStatus() == PlayStatus.PLAYING) {
                    window.setPrivateFatio(fRatio)
                }
            }
        }
    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        startUpdate()
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        cancelUpdate()
    }

    /**
     * 开始刷新流量
     */
    private fun startUpdate() {
        viewBinding.root.postDelayed(trafficRefreshTask, 1000L)
    }

    /**
     * 停止刷新流量
     */
    private fun cancelUpdate() {
        viewBinding.root.removeCallbacks(trafficRefreshTask)
    }


    /**
     * 刷新数据流量的任务
     */
    private val trafficRefreshTask = Runnable {
        var streamFlow: Long = 0
        var mLastDataLength: Long = 0
        windowGroupHelper?.windowItemStructAllList?.let { windowList ->
            windowList.forEach { view ->
                val window = view as PlayWindowView
                if (window.getPlayStatus() == PlayStatus.PLAYING) {
                    streamFlow += window.getTotalTraffic()
                    mLastDataLength += window.lastTotalTraffic
                    window.lastTotalTraffic = window.getTotalTraffic()
                }
            }
            if (streamFlow - mLastDataLength > 0) {
                totalTraffic += streamFlow - mLastDataLength
            }
            val content = MessageFormat.format(
                "{0} {1}",
                TrafficUtils.getCurrentTraffic(streamFlow - mLastDataLength),
                TrafficUtils.getTotalTraffic(totalTraffic)
            )
            viewBinding.trafficText.text = content
            startUpdate()
        }
    }


    override fun onClick(v: View?) {
        when (v?.id) {
            R.id.openHardDecodeButton -> {
                setHardDecode(true)
            }
            R.id.closeHardDecodeButton -> {
                setHardDecode(false)
            }
            R.id.openSmartButton -> {
                setSmartDetect(true)
            }
            R.id.closeSmartButton -> {
                setSmartDetect(false)
            }
            R.id.startPreviewButton -> {
                startPreview()
            }
            R.id.stopPreviewButton -> {
                stopPreview()
            }
            R.id.startTalkButton -> {
                startVoiceTalk()
            }
            R.id.stopTalkButton -> {
                stopVoiceTalk()
            }
            R.id.openSoundButton -> {
                openSound()
            }
            R.id.closeSoundButton -> {
                closeSound()
            }
            R.id.captureButton -> {
                capture()
            }
            R.id.startRecordButton -> {
                startRecord()
            }
            R.id.stopRecordButton -> {
                stopRecord()
            }
            R.id.openFishEyeButton -> {
                openFishEye()
            }
            R.id.exitFishEyeButton -> {
                closeFishEye()
            }
            R.id.fish180Button -> {
                setFishEyeMode(CorrectType.FEC_CORRECT_180)
            }
            R.id.fish360Button -> {
                setFishEyeMode(CorrectType.FEC_CORRECT_360)
            }
            R.id.fishOriginButton -> {
                setFishEyeMode(CorrectType.FEC_CORRECT_LAT)
            }
            R.id.fishPtzButton -> {
                setFishEyeMode(CorrectType.FEC_CORRECT_PTZ)
            }
            R.id.fishSemButton -> {
                setFishEyeMode(CorrectType.FEC_CORRECT_SEM)
            }
            R.id.fishCycButton -> {
                setFishEyeMode(CorrectType.FEC_CORRECT_CYC)
            }
            R.id.fishCycSplButton -> {
                setFishEyeMode(CorrectType.FEC_CORRECT_CYC_SPL)
            }
            R.id.fishPlaButton -> {
                setFishEyeMode(CorrectType.FEC_CORRECT_PLA)
            }
            R.id.halfRateButton -> {
                setExpectedRate()
            }
            R.id.getRateButton -> {
                getFrameRate()
            }
            R.id.decodeButton -> {
                setDecodeThread()
            }
            else -> {
            }
        }
    }


    /**
     * 设置硬解码
     */
    private fun setHardDecode(isHardDecode: Boolean) {
        windowGroupHelper?.currentWindowItem?.let {
            val playWindowView = it as PlayWindowView
            if (playWindowView.getPlayStatus() == PlayStatus.PLAYING) {
                Toast.makeText(context, "请在播放之前设置", Toast.LENGTH_SHORT).show()
                return@let
            }
            playWindowView.setHardDecodePlay(isHardDecode)
            val content = if (isHardDecode) "硬解码开" else "硬解码关"
            Toast.makeText(context, content, Toast.LENGTH_SHORT).show()
        }
    }

    /**
     * 设置智能信息
     */
    private fun setSmartDetect(isSmartDetect: Boolean) {
        windowGroupHelper?.currentWindowItem?.let {
            val playWindowView = it as PlayWindowView
            if (playWindowView.getPlayStatus() == PlayStatus.PLAYING) {
                Toast.makeText(context, "请在播放之前设置", Toast.LENGTH_SHORT).show()
                return@let
            }
            playWindowView.setSmartDetect(isSmartDetect)
            val content = if (isSmartDetect) "智能信息开" else "智能信息关"
            Toast.makeText(context, content, Toast.LENGTH_SHORT).show()
        }
    }

    /**
     * 开启预览
     */
    private fun startPreview() {
        windowGroupHelper?.currentWindowItem?.let {
            val previewUrl = viewBinding.previewUrlEdit.text.toString()
            if (previewUrl.isEmpty()) {
                Toast.makeText(context, "请输入预览Url", Toast.LENGTH_SHORT).show()
                return@let
            }
            val playWindowView = it as PlayWindowView
            if (playWindowView.getPlayStatus() == PlayStatus.PLAYING) {
                //平滑切换
                playWindowView.changeStream(url = previewUrl)
            } else {
                playWindowView.startPlay(previewUrl)
            }
        }
    }

    /**
     * 关闭预览
     */
    private fun stopPreview() {
        windowGroupHelper?.currentWindowItem?.let {
            val playWindowView = it as PlayWindowView
            playWindowView.stopPlay()
            playWindowView.showPlayIdle()
            viewBinding.getRateButton.text = resources.getString(R.string.frame_rate_get)
        }
    }

    /**
     * 开启对讲
     */
    private fun startVoiceTalk() {
        windowGroupHelper?.currentWindowItem?.let {
            val talkUrl = viewBinding.talkUrlEdit.text.toString()
            if (talkUrl.isEmpty()) {
                Toast.makeText(context, "请输入对讲Url", Toast.LENGTH_SHORT).show()
                return@let
            }
            val activity = MyUtils.getActivity(this) as? FragmentActivity ?: return
            //进行权限判断
            if (PermissionHelper.isGranted(activity, Manifest.permission.RECORD_AUDIO)) {
                doOpenVoiceTalk(it, talkUrl)
            } else {
                //请求权限
                PermissionHelper.requestRecordAudioPermission(activity) { allGranted ->
                    if (allGranted) {
                        doOpenVoiceTalk(it, talkUrl)
                    }
                }
            }
        }
    }

    private fun doOpenVoiceTalk(
        it: WindowItemView,
        talkUrl: String
    ) {
        //开启对讲的时候要把所有窗口声音、对讲，都关掉
        val windowList = windowGroupHelper?.windowItemStructAllList ?: emptyList()
        windowList.forEach { windowItemView ->
            val playWindowView = windowItemView as PlayWindowView
            if (playWindowView.isVoiceTalking) {
                playWindowView.closeVoiceTalk()
            }
            playWindowView.hideVoiceTalkHint()
            if (playWindowView.isOpenAudio) {
                playWindowView.executeSound()
            }
        }
        val playWindowView = it as PlayWindowView
        playWindowView.openVoiceTalk(talkUrl)
    }

    /**
     * 停止对讲
     */
    private fun stopVoiceTalk() {
        windowGroupHelper?.currentWindowItem?.let {
            val playWindowView = it as PlayWindowView
            playWindowView.closeVoiceTalk()
        }
    }

    /**
     * 开启声音
     */
    private fun openSound() {
        windowGroupHelper?.currentWindowItem?.let {
            val playWindowView = it as PlayWindowView
            if (playWindowView.getPlayStatus() != PlayStatus.PLAYING) {
                Toast.makeText(context, "没有视频在播放", Toast.LENGTH_SHORT).show()
                return@let
            }
            if (playWindowView.isPause) {
                Toast.makeText(context, "视频已暂停", Toast.LENGTH_SHORT).show()
                return@let
            }
            if (!playWindowView.isOpenAudio) {
                playWindowView.executeSound()
                Toast.makeText(context, "声音已打开", Toast.LENGTH_SHORT).show()
            }
        }
    }

    /**
     * 关闭声音
     */
    private fun closeSound() {
        windowGroupHelper?.currentWindowItem?.let {
            val playWindowView = it as PlayWindowView
            if (playWindowView.getPlayStatus() != PlayStatus.PLAYING) {
                Toast.makeText(context, "没有视频在播放", Toast.LENGTH_SHORT).show()
                return@let
            }
            if (playWindowView.isOpenAudio) {
                playWindowView.executeSound()
                Toast.makeText(context, "声音已关闭", Toast.LENGTH_SHORT).show()
            }
        }
    }


    /**
     * 抓拍
     */
    private fun capture() {
        //进行权限判断
        if (PermissionHelper.isGranted(context, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            doCapture()
        } else {
            //请求权限
            val activity = MyUtils.getActivity(this) as? FragmentActivity ?: return
            PermissionHelper.requestStoragePermission(activity) { allGranted ->
                if (allGranted) {
                    doCapture()
                }
            }
        }
    }

    private fun doCapture() {
        windowGroupHelper?.currentWindowItem?.let {
            val playWindowView = it as PlayWindowView
            if (playWindowView.getPlayStatus() != PlayStatus.PLAYING) {
                Toast.makeText(context, "没有视频在播放", Toast.LENGTH_SHORT).show()
                return@let
            }
            playWindowView.executeCapture()
            Toast.makeText(context, "抓图成功", Toast.LENGTH_SHORT).show()
        }
    }

    /**
     * 开启录像
     */
    private fun startRecord() {
        //进行权限判断
        if (PermissionHelper.isGranted(context, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            doStartRecord()
        } else {
            //请求权限
            val activity = MyUtils.getActivity(this) as? FragmentActivity ?: return
            PermissionHelper.requestStoragePermission(activity) { allGranted ->
                if (allGranted) {
                    doStartRecord()
                }
            }
        }
    }

    private fun doStartRecord() {
        windowGroupHelper?.currentWindowItem?.let {
            val playWindowView = it as PlayWindowView
            if (playWindowView.getPlayStatus() != PlayStatus.PLAYING) {
                Toast.makeText(context, "没有视频在播放", Toast.LENGTH_SHORT).show()
                return@let
            }
            if (playWindowView.isPause) {
                Toast.makeText(context, "视频已暂停", Toast.LENGTH_SHORT).show()
                return@let
            }
            if (!playWindowView.isRecording) {
                val recordPath = playWindowView.executeRecord()
                Toast.makeText(context, "开始录像", Toast.LENGTH_SHORT).show()
                viewBinding.recordPathText.text = recordPath
            }
        }
    }

    /**
     * 关闭录像
     */
    private fun stopRecord() {
        windowGroupHelper?.currentWindowItem?.let {
            val playWindowView = it as PlayWindowView
            if (playWindowView.getPlayStatus() != PlayStatus.PLAYING) {
                Toast.makeText(context, "没有视频在播放", Toast.LENGTH_SHORT).show()
                return@let
            }
            if (playWindowView.isRecording) {
                playWindowView.executeRecord()
                Toast.makeText(context, "关闭录像", Toast.LENGTH_SHORT).show()
            }
        }
    }

    /**
     * 打开鱼眼模式
     */
    private fun openFishEye() {
        windowGroupHelper?.currentWindowItem?.let {
            val playWindowView = it as PlayWindowView
            if (playWindowView.getPlayStatus() != PlayStatus.PLAYING) {
                Toast.makeText(context, "没有视频在播放", Toast.LENGTH_SHORT).show()
                return@let
            }
            if (playWindowView.openFishEye()) {
                Toast.makeText(context, "打开鱼眼成功！", Toast.LENGTH_SHORT).show()
            } else {
                Toast.makeText(context, "打开鱼眼失败", Toast.LENGTH_SHORT).show()
            }
        }
    }

    /**
     * 关闭鱼眼模式
     */
    private fun closeFishEye() {
        windowGroupHelper?.currentWindowItem?.let {
            val playWindowView = it as PlayWindowView
            if (playWindowView.getPlayStatus() != PlayStatus.PLAYING) {
                Toast.makeText(context, "没有视频在播放", Toast.LENGTH_SHORT).show()
                return@let
            }
            playWindowView.closeFishEyeMode()
            Toast.makeText(context, "关闭鱼眼成功！", Toast.LENGTH_SHORT).show()
        }
    }

    /**
     * 设置鱼眼矫正类型
     */
    private fun setFishEyeMode(@CorrectType correctType: Int) {
        windowGroupHelper?.currentWindowItem?.let {
            val playWindowView = it as PlayWindowView
            if (playWindowView.getPlayStatus() != PlayStatus.PLAYING) {
                Toast.makeText(context, "没有视频在播放", Toast.LENGTH_SHORT).show()
                return@let
            }
            if (!playWindowView.isOpenFishEyeMode) {
                Toast.makeText(context, "请先开启鱼眼模式", Toast.LENGTH_SHORT).show()
                return@let
            }
            playWindowView.setFishEyeMode(correctType)
        }
    }

    /**
     * 获取码流帧率
     */
    private fun getFrameRate() {
        windowGroupHelper?.currentWindowItem?.let {
            val playWindowView = it as PlayWindowView
            if (playWindowView.getPlayStatus() != PlayStatus.PLAYING) {
                Toast.makeText(context, "没有视频在播放", Toast.LENGTH_SHORT).show()
                return@let
            }
            val rate = playWindowView.getFrameRate()
            viewBinding.getRateButton.text =
                "${resources.getString(R.string.frame_rate_get)}: $rate"
        }
    }

    /**
     * 设置当前帧率减半
     */
    private fun setExpectedRate() {
        windowGroupHelper?.currentWindowItem?.let {
            val playWindowView = it as PlayWindowView
            if (playWindowView.getPlayStatus() != PlayStatus.PLAYING) {
                Toast.makeText(context, "没有视频在播放", Toast.LENGTH_SHORT).show()
                return@let
            }
            val rate = viewBinding.rateEdit.text.toString()
            if (rate.isEmpty()) {
                Toast.makeText(context, "请输入预期帧率", Toast.LENGTH_SHORT).show()
                return@let
            }
            val targetRate = rate.toFloat()
            if (targetRate < 1 || targetRate > playWindowView.getFrameRate()) {
                Toast.makeText(context, "超出码流帧率，设置不生效", Toast.LENGTH_SHORT).show()
                return@let
            }
            if (playWindowView.setExpectedFrameRate(targetRate)) {
                Toast.makeText(context, "设置帧率成功，帧率改为 $targetRate", Toast.LENGTH_SHORT).show()
            } else {
                Toast.makeText(context, "设置帧率失败", Toast.LENGTH_SHORT).show()
            }
        }
    }

    private fun setDecodeThread() {
        windowGroupHelper?.currentWindowItem?.let {
            val playWindowView = it as PlayWindowView
            if (playWindowView.getPlayStatus() != PlayStatus.PLAYING) {
                Toast.makeText(context, "没有视频在播放", Toast.LENGTH_SHORT).show()
                return@let
            }
            if (playWindowView.setDecodeThread()) {
                Toast.makeText(context, "设置8线程解码成功", Toast.LENGTH_SHORT).show()
            } else {
                Toast.makeText(context, "设置8线程解码失败，此操作只支持软解", Toast.LENGTH_SHORT).show()
            }
        }

    }
}